package handledb;

import java.lang.reflect.Field;
import java.sql.ResultSet;
import java.sql.ResultSetMetaData;
import java.sql.SQLException;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;

public class ResultSetHandle {
    private static final String strFields = "VARCHAR,DATETIME,CHAR,TIMESTAMP,TINYTEXT,TEXT,LONGTEXT,MEDIUMTEXT,YEAR,DATE,TIME,TINYBLOB,BLOB,MEDIUMBLOB,LONGBLOB";

    private static Date setDate(String str) throws ParseException {
        char[] cs = str.toCharArray();
        char[] cs2 = new char[16];
        String format = "";
        char c = 0;
        int len = cs.length;
        int j = 0;
        int k = 0;
        int n = 0;
        for (int i = 0; i < len; i++) {
            if (j < 14) {
                c = cs[i];
                if (' ' == c) {
                    if (k == 1) {
                        cs2[j] = cs2[j - 1];
                        cs2[j - 1] = '0';
                        j++;
                    }
                    if (n == 2) {
                        format += "dd";
                        n++;
                    }
                    k = -1;
                } else {
                    if (c < '0' || '9' < c) {
                        if (n == 0) {
                            format = "yyyy";
                            if (k == 2) {
                                format = "yy";
                            } else if (k == 3) {
                                format = "yyy";
                            }
                        } else if (n == 1) {
                            format += "MM";
                        } else if (n == 2) {
                            format += "dd";
                        } else if (n == 3) {
                            format += "HH";
                        } else if (n == 4) {
                            format += "mm";
                        } else if (n == 5) {
                            format += "ss";
                        }
                        n++;
                        if (k == 1) {
                            cs2[j] = cs2[j - 1];
                            cs2[j - 1] = '0';
                            j++;
                        }
                        k = -1;
                    }
                }
                k++;
                if (k > 0) {
                    cs2[j++] = c;
                }
            }
        }
        if (k == 1) {
            cs2[j] = cs2[j - 1];
            cs2[j - 1] = '0';
            j++;
        }
        if (n == 2) {
            format += "dd";
        } else if (n == 3) {
            format += "HH";
        } else if (n == 4) {
            format += "mm";
        } else if (n == 5) {
            format += "ss";
        }
        return new SimpleDateFormat(format).parse(new String(cs2));
    }

    private static Object setValue(Object obj, int type, Field f, String str) throws IllegalArgumentException, IllegalAccessException, ParseException {
        if (str == null) return obj;
        switch (type) {
            case 1:
                f.set(obj, str);
                break;
            case 2:
                f.set(obj, Integer.parseInt(str));
                break;
            case 3:
                f.set(obj, Long.parseLong(str));
                break;
            case 4:
                f.set(obj, setDate(str));
                break;
            case 5:
                f.set(obj, Double.parseDouble(str));
                break;
            case 6:
                f.set(obj, Float.parseFloat(str));
                break;
            case 7:
                f.set(obj, Short.parseShort(str));
                break;
        }
        return obj;
    }

    public static <T> T resultSetToObject(ResultSet rs, ClassInfo classInfo) {
        Object obj = null;
        try {
            if (rs.next()) {
                obj = classInfo.con.newInstance();
                ResultSetMetaData rsmd = rs.getMetaData();
                int len = rsmd.getColumnCount();
                String[] strs = new String[len];
                for (int i = 0; i < len; i++) {
                    strs[i] = rsmd.getColumnLabel(i + 1).toLowerCase();
                }
                String str = "";
                for (int i = 0; i < strs.length; ) {
                    str = strs[i];
                    i += 1;
                    for (FieldInfo info : classInfo.allFieldInfos) {
                        if (str.equals(info.columnName)) {
                            setValue(obj, info.type, info.field, rs.getString(i));
                            break;
                        }
                    }
                }
            }
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
        return (T) obj;
    }

    public static <T> List<T> resultSetToList(ResultSet rs, ClassInfo classInfo) {
        List<T> list = new ArrayList<>();
        Object obj = null;
        try {
            ResultSetMetaData rsmd = rs.getMetaData();
            int len = rsmd.getColumnCount();
            String[] strs = new String[len];
            for (int i = 0; i < len; i++) {
                strs[i] = rsmd.getColumnLabel(i + 1).toLowerCase();
            }
            String str = "";
            FieldInfo[] fields = new FieldInfo[len];
            for (int i = 0; i < strs.length; i++) {
                str = strs[i];
                for (FieldInfo info : classInfo.allFieldInfos) {
                    if (str.equals(info.columnName)) {
                        fields[i] = info;
                        break;
                    }
                }
            }
            while (rs.next()) {
                obj = classInfo.con.newInstance();  //通过反射机制创建一个新的对象
                FieldInfo info = null;
                for (int j = 0; j < len; ) {   //遍历结果集，并把值赋给对象
                    info = fields[j];
                    j += 1;
                    if (info != null) {
                        setValue(obj, info.type, info.field, rs.getString(j));
                    }
                }
                list.add((T) obj);
            }
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
        return list;
    }

    public static String resultSetToJson(ResultSet rs, ClassInfo classInfo) {
        String json = null;
        try {
            StringBuffer sb = new StringBuffer();
            ResultSetMetaData rsmd = rs.getMetaData();
            int len = rsmd.getColumnCount();
            String[] strs = new String[len];
            for (int i = 0; i < len; i++) {
                strs[i] = rsmd.getColumnLabel(i + 1).toLowerCase();
            }
            String str = "";
            String alertStr = "";
            FieldInfo[] fields = new FieldInfo[len];
            int k = 0;
            for (int i = 0; i < strs.length; i++) {
                str = strs[i];
                for (FieldInfo info : classInfo.allFieldInfos) {
                    if (str.equals(info.columnName)) {
                        fields[i] = info;
                        k++;
                        break;
                    }
                }
                if (fields[i] == null) {
                    alertStr += str + ",";
                }
            }
            if (len > k) {
                throw new RuntimeException("the number of columns is inconsistent with the number of attribute names[" + alertStr + "]");
            }
            int n = k - 1;
            FieldInfo fieldInfo = null;
            int size = 0;
            while (rs.next()) {
                sb.append("{");
                String value = "";
                String cValue = null;
                for (int j = 0; j < len; j++) {   //遍历结果集，并把值赋给对象
                    fieldInfo = fields[j];
                    cValue = rs.getString(j + 1);
                    if (cValue == null) {
                        value = "null";
                    } else {
                        if (fieldInfo.type == 1) {
                            value = "\"" + cValue + "\"";
                        } else if (fieldInfo.type == 4) {
                            value = "\"" + new SimpleDateFormat(fieldInfo.format).format(setDate(cValue)) + "\"";
                        } else {
                            value = cValue;
                        }
                    }
                    if (j < n) sb.append("\"").append(fieldInfo.name).append("\":").append(value).append(",");
                    else sb.append("\"").append(fieldInfo.name).append("\":").append(value);
                }
                sb.append("},");
                size++;
            }
            if (size > 0) {
                json = sb.substring(0, sb.length() - 1);
                if (size > 1) json = "[" + json + "]";
            }
        } catch (Exception e) {
            throw new RuntimeException(e);
        }
        return json;
    }


    public static String tojson(ResultSet rs) {
        int len = 0;
        int size = 0;
        StringBuffer sb = new StringBuffer();
        String str = "";
        if (rs == null) {
            return "";
        }
        try {
            ResultSetMetaData rsmd = rs.getMetaData();
            len = rsmd.getColumnCount();
            String[] columns = new String[len];
            boolean[] hasStr = new boolean[len];
            for (int i = 0; i < len; i++) {    //获取列名
                columns[i] = rsmd.getColumnLabel(i + 1).toLowerCase();
                hasStr[i] = strFields.indexOf(rsmd.getColumnTypeName(i + 1)) > -1;
            }
            String ss = null;
            int n = len - 1;
            while (rs.next()) {
                sb.append("{");
                for (int i = 0; i < len; i++) {
                    ss = rs.getString(i + 1);
                    if (ss == null) {
                        ss = "null";
                    } else if (hasStr[i]) {
                        ss = "\"" + ss + "\"";
                    }
                    if (i < n) {
                        sb.append("\"").append(columns[i]).append("\":").append(ss).append(",");
                    } else {
                        sb.append("\"").append(columns[i]).append("\":").append(ss);
                    }
                }
                sb.append("},");
                size++;
            }
            if (size > 0) {
                str = sb.toString();
                str = str.substring(0, str.length() - 1);
            }
        } catch (SQLException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
        if (size > 1) {
            str = "[" + str + "]";
        }
        return str;
    }
}

